package com.zhijiang.common.util;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;

import javax.xml.ws.Endpoint;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * webservice 请求工具类
 */
@Slf4j
public class CallWebServiceUtils {

    private static String soapStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"namespaceData\">" +
            "   <soapenv:Header/>" +
            "   <soapenv:Body>" +
            "       <web:interfaceNameData>" +
            "           <web:function>functionData</web:function>" +
            "           <web:json>jsonData</web:json>" +
            "       </web:interfaceNameData>" +
            "   </soapenv:Body>" +
            "</soapenv:Envelope>";


    public static String callWebServiceByHttp(String urlWsdl,String namespace, String SOAPAction,String interfaceName,String function, String json){
        log.info("callWebServiceByHttp begin json:{}",json);

        /** 关键参数替换 */
        String soapXML = soapStr.replaceAll("namespaceData",namespace)
                .replaceAll("interfaceNameData",interfaceName)
                .replaceAll("functionData",function)
                .replaceAll("jsonData", json);

        HttpURLConnection connection = null;
        try {
            URL url = new URL(urlWsdl);
            connection = (HttpURLConnection)url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
            connection.setRequestProperty("SOAPAction", SOAPAction);
            connection.connect();

            setBytesToOutputStream(connection.getOutputStream(), soapXML.getBytes());

            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                byte[] b = getBytesFromInputStream(connection.getInputStream());
                String back = new String(b);

                log.info("callWebServiceByHttp end json:{} back:{}", json,JSONObject.toJSONString(back));

                String returnData = parseResult(back);

                log.info("callWebServiceByHttp end returnData:{}",returnData);
                return returnData;
            } else {
                log.error("callWebServiceByHttp json:{} httpURLConnection返回状态码:{}",json,connection.getResponseCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null){
                connection.disconnect();
            }
        }
        log.error("callWebServiceByHttp error json:{}",json);
        return null;
    }

    /**
     * 向输入流发送数据
     * @param out
     * @param bytes
     * @throws IOException
     */
    private static void setBytesToOutputStream(OutputStream out, byte[] bytes) throws IOException {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        byte[] b = new byte[1024];
        int len;
        while ((len = bais.read(b)) != -1) {
            out.write(b, 0, len);
        }
        out.flush();
    }

    /**
     * 从输入流获取数据
     * @param in
     * @return
     * @throws IOException
     */
    private static byte[] getBytesFromInputStream(InputStream in) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int len;
        while ((len = in.read(b)) != -1) {
            baos.write(b, 0, len);
        }
        byte[] bytes = baos.toByteArray();
        return bytes;
    }


    /**
     * 解析结果
     * @param s
     * @return
     */
    private static String parseResult(String s) {
        String result = "";
        try {
            Reader file = new StringReader(s);
            SAXReader reader = new SAXReader();

            Map<String, String> map = new HashMap<String, String>();
            // 这个替换为targetNamespace
            map.put("ns", "http://XXXXXX");
            reader.getDocumentFactory().setXPathNamespaceURIs(map);
            Document dc = reader.read(file);
            // 这个节点改成你们对应客户接口返回xml格式的数据节点
            result = dc.selectSingleNode("//ns:InfInterfaceForJsonResult").getText().trim();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
